package it.unisannio.lesim.fsm;

import it.unisannio.lesim.fsm.exception.UnrecognizedExpressionException;
import java.util.Hashtable;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Marco Calisti
 * @author Antonio Cuomo
 * @author Rocco Mazzeo
 * @author Francesco Pacilio
 * 
 */

public class Transition {
           
    private String nextState;
    private String condition;
    private String action;
    private FSM fsm;
    
    public Transition(FSM fsm, String nextState, String cond, String action){
        this.fsm=fsm;
        this.nextState=nextState;
        this.condition=cond;
        this.action= action;
    }
    
    public String getAction() {
        return action;
    }

    public String getCondition() {
        return condition;
    }
    
    public boolean check(long time, String typeMessage, Hashtable fields, long messageTime){
        BooleanExpressionEvaluator bEval= new BooleanExpressionEvaluator();
        try {
                boolean match;
             if(condition==null)
                match=true;
             else
                match= bEval.evaluateBooleanExpression(condition, fsm.getStorage(), typeMessage, fields, time, messageTime);
             if(action!=null && match){
                ActionPerformer ae= new ActionPerformer();//Do action
                ae.performAction(action, fsm.getStorage(), typeMessage, fields, time, messageTime);
             }
             return match;
        } catch (UnrecognizedExpressionException ex) {
            Logger.getLogger(Transition.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }
     
    /*
    public boolean check(int time, String typeMessage, Hashtable fields) {       
        // timeless, timegreat, type , exp
        ExpressionEvaluator ee = new ExpressionEvaluator();
        
        /*
        if(cond.getTimeLess()==-1) {
            if(cond.getTimeGreat()==-1) {
                if(cond.getType()==null) {
                    if(cond.getFieldExpression()==null) return false;
                    else {
                        return ee.evaluateExpression(cond.getFieldExpression(), fields);
                    }
                    
                }
                else {
                     if(cond.getFieldExpression()==null)  return typeMessage.equals(cond.getType());                     
                     else return (ee.evaluateExpression(cond.getFieldExpression(), fields) && typeMessage.equals(cond.getType()));
                }
            }
            else {
                if(cond.getType()==null) {
                    if(time>cond.getTimeGreat() && cond.getFieldExpression()==null) return false;
                    else {
                        return (time>cond.getTimeGreat() && ee.evaluateExpression(cond.getFieldExpression(), fields));
                    }
                    
                }
                else {
                     if(cond.getFieldExpression()==null)  return typeMessage.equals(cond.getType());                     
                     else return (time>cond.getTimeGreat() && ee.evaluateExpression(cond.getFieldExpression(), fields) && typeMessage.equals(cond.getType()));
                }
            }
        }
        else {
             if(cond.getTimeGreat()==-1) {
                if(cond.getType()==null) {
                    if(time<=cond.getTimeLess() && cond.getFieldExpression()==null) return false;
                    else {
                        return (time<=cond.getTimeLess() && ee.evaluateExpression(cond.getFieldExpression(), fields));
                    }
                    
                }
                else {
                     if(cond.getFieldExpression()==null)  return (time<=cond.getTimeLess() && typeMessage.equals(cond.getType()));                     
                     else return (time<=cond.getTimeLess() && ee.evaluateExpression(cond.getFieldExpression(), fields) && typeMessage.equals(cond.getType()));
                }
            }
            else {
                if(cond.getType()==null) {
                    if(time<=cond.getTimeLess() && time>cond.getTimeGreat() && cond.getFieldExpression()==null) return false;
                    else {
                        return (time<=cond.getTimeLess() && time>cond.getTimeGreat() && ee.evaluateExpression(cond.getFieldExpression(), fields));
                    }
                    
                }
                else {
                     if(cond.getFieldExpression()==null)  return (time<=cond.getTimeLess() && typeMessage.equals(cond.getType()));                     
                     else return (time<=cond.getTimeLess() && time>cond.getTimeGreat() && ee.evaluateExpression(cond.getFieldExpression(), fields) && typeMessage.equals(cond.getType()));
                }
            }
        }
        */
 /*
        Vector conditions = cond.getConditions();
         
        boolean check = true;
        
        for(int i=0; i<conditions.size(); i++){
            if(((String)conditions.get(i)).equals("timeLess")){
                check = check && time<=cond.getTimeLess();
            }
            if(((String)conditions.get(i)).equals("timeGreat")){
                check = check && time>cond.getTimeGreat();
            }
            if(((String)conditions.get(i)).equals("type")){
                check = check && typeMessage.equals(cond.getType());
            }
            if(((String)conditions.get(i)).equals("fieldExpression")){
                check = check && ee.evaluateExpression(cond.getFieldExpression(), fields);
            }
        }

        return check;
    }*/
    
    public String getNextState(){
        return nextState;
    } 
    
}
